package com.ehotting.mqbd.zw.netty.netty;

import com.alibaba.fastjson.JSON;
import com.ehotting.eaf.netty.client.TcpClient;
import com.ehotting.eaf.netty.loggers.NettyMsgSendLogger;
import com.ehotting.eaf.netty.sync.SyncFutureMapHelper;
import com.ehotting.edsta.mqbd.api.enums.SysModuleEnum;
import com.ehotting.mqbd.core.manager.SolverStateManager;
import com.ehotting.mqbd.zw.api.domain.netty.ShakeHandReq;
import com.ehotting.mqbd.zw.api.domain.netty.ZwCommPacket;
import org.slf4j.MDC;

public class ZwTcpClient extends TcpClient {

    private SyncFutureMapHelper<ZwCommPacket> zwNettySyncFutureMapHelper;
    private NettyMsgSendLogger nettyMsgSendLogger;
    private SolverStateManager solverStateManager;

    public void setNettyMsgSendLogger(NettyMsgSendLogger nettyMsgSendLogger) {
        this.nettyMsgSendLogger = nettyMsgSendLogger;
    }

    public void setZwNettySyncFutureMapHelper(SyncFutureMapHelper<ZwCommPacket> zwNettySyncFutureMapHelper) {
        this.zwNettySyncFutureMapHelper = zwNettySyncFutureMapHelper;
    }

    @Override
    public void success() {
       logger.info("Client connect to zwServer[ip:"+ip+",port:"+port+"] success");
        /**连接成功，发送握手指令**/
        sendZwPkg(new ShakeHandReq());
        solverStateManager.saveSolverAvailable(SysModuleEnum.SIMULATION.getCode(),ip,String.valueOf(port));
    }

    @Override
    public void fail() {
        logger.error("server[ip:"+ip+",port:"+port+"] connect to zwServer fail");
        //solverStateManager.saveServerStop(SysModuleEnum.SIMULATION.getCode(),ip,String.valueOf(port));
    }

    public void sendZwPkg(ZwCommPacket msg) {
        this.getChannel();
        channel.writeAndFlush(msg);
    }

    /**
     * 同步发送
     * @param data
     * @param timeout
     * @param sync
     * @return
     */
    public ZwCommPacket request(ZwCommPacket data, long timeout, boolean sync){
        MDC.put(NettyMsgSendLogger.REQUEST, JSON.toJSONString(data));
        MDC.put(NettyMsgSendLogger.START_TIME, String.valueOf(System.currentTimeMillis()));
        ZwCommPacket msg = null;
        try {
            // 使用cmd和peerPackId组成key，后续需要根据这个获取响应
            String key = data.getHead().getCmd()+"-"+data.getHead().getPeerPackId();
            if(sync ) {
                logger.info("data.getHead().getPeerPackId():{}", key);
                zwNettySyncFutureMapHelper.set(key);
            }
            sendZwPkg(data);
            if(sync ) {
                msg = zwNettySyncFutureMapHelper.get(key, timeout);
                MDC.put(NettyMsgSendLogger.RESPONSE, JSON.toJSONString(msg));
            }
        } catch (InterruptedException e) {
            MDC.put(NettyMsgSendLogger.EXCEPTION,"request time out("+timeout+"s)");
            e.printStackTrace();
        }finally{
            nettyMsgSendLogger.info();
        }
        return msg;
    }

    public void setSolverStateManager(SolverStateManager solverStateManager) {
        this.solverStateManager = solverStateManager;
    }
}
